前七天,我們的Agent已經具備了傲嬌靈魂與長期記憶。但如果今天使用者不只是想跟她談戀愛(?),而是希望她幫忙「寫程式」、「算數」或「查資料」時...
如果在那邊:「哼!15 乘 32 等於多少我才不告訴你呢!笨蛋!」,這不叫傲嬌,這叫「無效溝通」啊!
為了讓 AI 在陪伴使用者的同時,又能隨時「切換成專業工作模式」,我們需要一個像是《刀劍神域》SYSTEM 控制權一樣的「大腦總機」,Intent Router(意圖路由器)!
今天的輕量任務:
router.py)
簡單來說,Intent Router 就像是動漫裡的「總部指揮中心」:
CHAT 日常閒聊 / 觸發好感度,TASK 啟動作戰模式 / 認真解任務)。router.py)我們利用 Gemini 輕量且極速的特性,撰寫一個專門用來「讀空氣」的分類器。
在專案目錄下新增 router.py:
from google import genai
from google.genai import types
ROUTER_SYSTEM_INSTRUCTION = """
你是一個精準的意圖分類器(警戒雷達)。請分析使用者的輸入,並嚴格只回傳以下其中一個標籤:
- CHAT:當使用者在打招呼、日常閒聊、開玩笑、感情諮詢、誇獎莉莉或進行角色互動時。
- TASK:當使用者提出明確的具體任務,例如要莉莉計算數學、寫代碼、翻譯文本、查詢資料或解決課業問題時。
"""
def classify_intent(client: genai.Client, user_input: str) -> str:
response = client.models.generate_content(
model='gemini-3.6-flash',
contents=user_input,
config=types.GenerateContentConfig(
system_instruction=ROUTER_SYSTEM_INSTRUCTION,
temperature=0.0,
)
)
# response.text 在模型回空字串、或被 safety filter 擋掉時會是 None,
# 直接 .strip() 會 AttributeError,所以用 or "" 墊底
intent = (response.text or "").strip().upper()
# 分不出來就一律當閒聊:誤判成 CHAT 只是回得傲嬌一點,
# 誤判成 TASK 會讓角色突然變成客服,體驗差得多
return intent if intent in ["CHAT", "TASK"] else "CHAT"
app.py 裝上「看眼色」的雷達別忘了在檔案頂部引入剛剛寫好的router模組:
import router
打開我們的 app.py,在呼叫 Agent 回應前,先讓 Router 進行判斷
try:
# 先發動意圖雷達判斷 (CHAT 或 TASK)
intent = router.classify_intent(client, user_input)
if intent == "CHAT":
# 走原本的莉莉傲嬌日常聊天路線
response = st.session_state.chat.send_message(user_input)
ai_reply = response.text
else:
# 切換成工作模式
# 這裡照樣用 send_message,只是用 config 覆寫這一輪的人設,
# 目的是讓這一輪仍然留在 chat 的 history 裡。
response = st.session_state.chat.send_message(
user_input,
config=types.GenerateContentConfig(
system_instruction="請以極度精準、高效率的方式完成使用者的任務,不要有任何傲嬌廢話或角色扮演。"
)
)
ai_reply = f"(哼!這種正經事就交給我吧)\n\n{response.text}"
except Exception as e:
# 這一輪完全不落地:session 和 Firestore 都維持送出前的狀態
st.error(f"角色沒有回應,API 出錯了:{e}")
st.info("這句話沒有被記錄,重新整理後會消失,可以直接再說一次。")
st.stop()
# 顯示 AI 角色的回應
with st.chat_message("assistant", avatar=AI_AVATAR):
st.write(ai_reply)
# 確定有回應了,才把這一輪的兩筆訊息一起存入 Session 與 Firestore
st.session_state.messages.append({"role": "user", "content": user_input})
save_message(st.session_state.user_id, "user", user_input)
st.session_state.messages.append({"role": "assistant", "content": ai_reply})
save_message(st.session_state.user_id, "assistant", ai_reply)
CHAT
TASK